<?

class Smutty_Controller_Smutty extends Smutty_Controller {

	function indexAction( $data, &$session ) {

		if ( !$session->user )
			$this->action( 'login' );
		else
			$this->_viewSmut( 'smutty/index.tpl' );

	}

	/**
	 *  access to models
	 *
	 */

	function checkModelsAccess( $session ) {

		$cfg = Smutty_Config::getInstance();

		// is anonymous access enabled?
		if ( $cfg->get('models.allowAnonymous') == 'true' )
			return;

		// no anon, require login
		if ( !$session->user ) {
			if ( $cfg->get('auth.type') )
				$this->redirect(array(
					action => 'login'
				));
			else new Smutty_Exception( 'you are not logged in', 'SmuttyModelManagement' );
		}

	}

	function modelsAction( $data, &$session ) {

		$this->checkModelsAccess($session);

		// load valid models
		$models = array();
		$dir = opendir( 'application/models/' );
		while ( $file = readdir($dir) )
			if ( preg_match('/(.*)\.php/',$file,$matches) ) {
				$modelClass = $matches[ 1 ];
				$models[ $modelClass ] = Smutty_Model::_getTotal( $modelClass );
				//array_push( $models, $matches[1] );
			}

		ksort( $models );

		$this->set( 'models', $models );
		$this->_viewSmut( 'smutty/models.tpl' );

	}

	function modelBrowseAction( $data, &$session ) {

		$this->checkModelsAccess($session);

		$modelClass = $data->string( 'smutty_modelClass' );
		$models = false;
		$fields = false;
		$total = Smutty_Model::_getTotal( $modelClass );

		// paging
		$perPage = 10;
		$limit = $perPage + 1;
		$start = $data->int( 'start' );
		$limit = $start ? "$start:$limit" : $limit;
		$more = false;
		$less = ( $start > 0 );
		$this->set( 'perPage', $perPage );
		$this->set( 'start', $start );
		$this->set( 'total', $total );

		eval( "\$models = $modelClass::fetchAll(false,false,\$limit);" );
		eval( "\$fields = $modelClass::_getFields();" );

		if ( sizeof($models) > $perPage ) {
			array_pop( $models );
			$more = true;
		}

		$this->set( 'more', $more );
		$this->set( 'less', $less );
		$this->set( 'modelClass', $modelClass );
		$this->set( 'models', $models );
		$this->set( 'fields', $fields );
		$this->set( 'relatedModels', $this->getRelatedModels($modelClass) );
		$this->_viewSmut( 'smutty/modelBrowse.tpl' );

	}

	function modelShowAction( $data, &$session ) {

		$this->checkModelsAccess($session);

		$modelClass = $data->string( 'smutty_modelClass' );
		$modelId = $data->int( 'smutty_modelId' );
		$model = false;
		$fields = false;

		eval( "\$model = $modelClass::find(\$modelId);" );
		eval( "\$fields = $modelClass::_getFields();" );

		$this->set( 'modelClass', $modelClass );
		$this->set( 'modelId', $modelId );
		$this->set( 'model', $model );
		$this->set( 'fields', $fields );
		$this->set( 'relatedModels', $this->getRelatedModels($modelClass) );
		$this->_viewSmut( 'smutty/modelShow.tpl' );
		
	}

	function modelEditAction( $data, &$session ) {

		$this->checkModelsAccess($session);

		$modelClass = $data->string( 'smutty_modelClass' );
		$modelId = $data->int( 'smutty_modelId' );
		$model = $data->object( 'model' ); // maybe passed through from save?
		$fields = false;

		if ( !$model )
			eval( "\$model = $modelClass::find( \$modelId );" );
		eval( "\$fields = $modelClass::_getFields();" );

		if ( !$model ) $model = new $modelClass();

		$this->set( 'model', $model );
		$this->set( 'fields', $fields );
		$this->set( 'modelClass', $modelClass );
		$this->set( 'modelId', $modelId );
		$this->_viewSmut( 'smutty/modelEdit.tpl' );

	}

	function modelSaveAction( &$data, &$session ) {

		$this->checkModelsAccess($session);

		$modelClass = $data->string( 'smutty_modelClass' );
		$modelId = $data->string( 'smutty_modelId' );

		$model = new $modelClass();
		$model->fill();
		$model->id = $modelId;

		if ( $model->save() )
			$this->redirect(array(
				action => 'modelShow',
				smutty_modelClass => $modelClass,
				smutty_modelId => $model->id
			));

		else {
			$data->set( 'model', $model );
			$this->action( 'modelEdit' );
		}

	}

	/**
	 *  fetches an array of model names which are
	 *  "related" to the specifed model class
	 *
	 *  @param [modelClass] related to
	 *  @return array
	 *
	 */

	function getRelatedModels( $modelClass ) {

		$model = new $modelClass();
		$related = array();
		$added = array();

		// check out the has strings
		$hasStrings = explode( ' ', $model->has_one . ' ' . $model->has_many );
		foreach ( $hasStrings as $hasString ) {
			$parts = explode( '.', $hasString );
			if ( ($class = $parts[0]) && !$added[strtolower($class)] ) {
				$related[] = $class;
				$added[ strtolower($class) ] = 1;
			}
		}

		// now look for fields that could match
		$fields = false;
		eval( "\$fields = $modelClass::_getFields();" );
		foreach ( $fields as $field )
			if ( substr($field->name,-3) == '_id' ) {
				$class = ucfirst(substr( $field->name, 0, strlen($field->name)-3 ));
				if ( class_exists($class) && !$added[strtolower($class)] ) {
					$related[] = $class;
					$added[ strtolower($class) ] = 1;
				}
			}

		return $related;

	}

	/**
	 *  handles a request for a smutty resource
	 *
	 */

	function resourceAction( $data ) {

		Smutty_Main::loadClass( 'Smutty_Resource' );

		$path = 'library/public/' .
			$data->string('folder') . '/' .
			$data->string('file');

		if ( file_exists($path) )
			Smutty_Resource::output( $path, true );

	}

	/**
	 *  this method provides built-in syndication for all models
	 *
	 */

	function rssAction( $data ) {

		$class = $data->string( 'model' );
		$class = ucfirst( $class );

		if ( class_exists($class) ) {

			$model = new $class();
			if ( !$model->rss )
				new Smutty_Exception( 'rss not valid for model', 'SmuttySyndication' );

			eval( "\$models = $class::fetchAll(false,array(),10);" );

			$tpl = new Smutty_Template_Smutty();
			$tpl->assign( 'modelName', $class );
			$tpl->assign( 'model', $model );
			$tpl->assign( 'models', $models );

			$tpl->display( 'syndication/rss-2.0.tpl' );

		}

	}

	/**
	 *  login and logout actions
	 *
	 */

	function loginAction( $data, $session ) {

		if ( $session->user )
			$this->redirect(array(
				action => 'index'
			));

		$cfg = Smutty_Config::getInstance();
		$type = $cfg->get( 'auth.type' );
		$file = "smutty/login-$type.tpl";

		switch ( $type ) {
			case 'standard':
				$name = $cfg->get('auth.standard.nameParam');
				$pass = $cfg->get('auth.standard.passParam');
				if ( !$name ) $name = 'username';
				if ( !$pass ) $pass = 'password';
				$this->set( 'nameParam', $name );
				$this->set( 'passParam', $pass );
				break;
			default:
				new Smutty_Exception( 'known auth type', 'ClassSmutty_Config' );
		}
		$this->_viewSmut( $file );

	}

	function logoutAction( $data, &$session ) {

		if ( $session->user )
			$session->user->logout();

		$this->redirect(array(
			action => 'login'
		));

	}

}

?>